package com.ly.heart.service.king;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.gson.Gson;
import com.kingdee.bos.webapi.entity.IdentifyInfo;
import com.kingdee.bos.webapi.entity.RepoRet;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ly.common.core.domain.entity.SysDept;
import com.ly.common.exception.CustomException;
import com.ly.common.utils.erp.CommonUtil;
import com.ly.common.utils.erp.KingConstUtil;
import com.ly.heart.domain.KingOrgEntity;
import com.ly.heart.domain.MaterialDetailEntity;
import com.ly.heart.domain.SaleOrderEntity;
import com.ly.heart.domain.king.BaseChildBo;
import com.ly.heart.domain.king.saleOrder.SaleOrderBo;
import com.ly.heart.domain.king.saleOrder.SaleOrderDetailBo;
import com.ly.heart.domain.king.saleOrder.SaleOrderFinanceBo;
import com.ly.heart.domain.request.KingBaseSingleRequest;
import com.ly.heart.domain.response.KingBaseResponse;
import com.ly.heart.domain.response.KingBaseResponseError;
import com.ly.heart.domain.response.KingBaseResponseSuccessEntity;
import com.ly.heart.domain.vo.SaleOrderCodeVo;
import com.ly.heart.service.IKingOrgService;
import com.ly.heart.service.IMaterialDetailService;
import com.ly.heart.service.ISaleOrderService;
import com.ly.heart.util.CurrentUserUtil;
import com.ly.heart.util.KingCommonUtil;
import com.ly.system.service.ISysDeptService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: Wuzh
 * @Description:
 * @Date Created in 16:05 2024-07-20
 * @return
 */
@Component
@Slf4j
public class SaleOrderPushService {

    @Resource
    private ISaleOrderService iSaleOrderService;
    @Resource
    private IMaterialDetailService iMaterialDetailService;
    @Resource
    private ISysDeptService iSysDeptService;
    @Resource
    private IKingOrgService iKingOrgService;

    public void push (String id) {
        KingOrgEntity orgEntity = iKingOrgService.getOne ( new LambdaQueryWrapper<KingOrgEntity> ().eq ( KingOrgEntity :: getOrgId, CurrentUserUtil.getCompanyId () ).eq ( KingOrgEntity :: getIsDisabled, true ) );
        if ( orgEntity == null ) {
            throw new CustomException ( "请先至系统管理中配置金蝶账套！" );
        }
        IdentifyInfo identifyInfo = KingCommonUtil.getIdentifyInfo ( orgEntity );
        K3CloudApi client = new K3CloudApi ( identifyInfo );
        SaleOrderCodeVo saleOrderCodeVo = iSaleOrderService.getSaleCodeById ( id );
        log.info ( "销售订单调用金蝶下推->{}", saleOrderCodeVo );
        if ( ObjectUtils.isEmpty ( saleOrderCodeVo ) ) {
            throw new CustomException ( "销售订单对象为空" );
        }
        if ( saleOrderCodeVo.getIsSend () == KingConstUtil.KING_DATA_IS_SEND_YES ) {
            throw new CustomException ( "该单据已推送金蝶，无需重复推送！" );
        }
        SaleOrderBo saleOrderBo = assembleSaleOrder ( saleOrderCodeVo );
        try {
            save ( saleOrderBo, client );
            submit ( saleOrderBo, client );
            audit ( saleOrderBo, client );
            updateSendSuccess ( id );
        } catch ( Exception e ) {
            e.printStackTrace ();
            throw new CustomException ( "销售订单推送失败，请稍后重试！" );
        }
    }

    /**
     * 推送付款单到金蝶
     * @param saleOrderBo
     * @param client
     * @throws Exception
     */
    private void save (SaleOrderBo saleOrderBo, K3CloudApi client) throws Exception {
        KingBaseSingleRequest singleRequest = new KingBaseSingleRequest ();
        singleRequest.setModel ( saleOrderBo );
        String s = JSONObject.toJSONString ( singleRequest );
        log.info ( "销售订单转JSON->{}", s );
        String resultJson = client.save ( KingConstUtil.SAL_SaleOrder, s );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () ) {
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "销售订单-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.info ( "{} 推送成功", sb );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "销售订单-推送失败：【" + sb + "】" );
        }
    }


    /**
     * 提交采购开票(应付单)到金蝶
     * @param bo
     * @param client
     */
    private void submit (SaleOrderBo bo, K3CloudApi client) throws Exception {
        List<String> strings = new ArrayList<> ();
        strings.add ( bo.getFBillNo () );
        bo.setNumbers ( strings );
        String jsonData = JSON.toJSONString ( bo );
        String resultJson = client.submit ( KingConstUtil.SAL_SaleOrder, jsonData );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () ) {
            //提交成功
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "销售订单-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.error ( "{} 提交成功", sb );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "销售订单-提交失败：【" + sb + "】" );
        }
    }

    /**
     * 审核应付单
     * @param bo
     * @param client
     */
    private void audit (SaleOrderBo bo, K3CloudApi client) throws Exception {
        List<String> strings = new ArrayList<> ();
        strings.add ( bo.getFBillNo () );
        bo.setNumbers ( strings );
        String jsonData = JSON.toJSONString ( bo );
        String resultJson = client.audit ( KingConstUtil.SAL_SaleOrder, jsonData );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () ) {
            //提交成功
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "销售订单-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.error ( "{} 审核成功", sb );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "销售订单审核失败：【" + sb + "】" );
        }
    }

    private void updateSendSuccess (String id) {
        SaleOrderEntity saleOrderEntity = iSaleOrderService.getById ( id );
        saleOrderEntity.setId ( id );
        saleOrderEntity.setIsSend ( KingConstUtil.KING_DATA_IS_SEND_YES );
        boolean b = iSaleOrderService.updateById ( saleOrderEntity );
        if ( ! b ) {
            throw new CustomException ( "修改推送金蝶状态失败！" );
        }
    }

    /**
     * 组装销售订单
     * @param saleOrderCodeVo
     * @return
     */
    private SaleOrderBo assembleSaleOrder (SaleOrderCodeVo saleOrderCodeVo) {
        SaleOrderBo bo = new SaleOrderBo ();
        //1.基
        bo.setFBillNo ( saleOrderCodeVo.getDocNo () );
        //单据类型
        BaseChildBo billType = new BaseChildBo ().setFNumber ( saleOrderCodeVo.getDocTypeCode () );
        bo.setFBillTypeID ( billType );
        //销售组织
        BaseChildBo FSaleOrgId = new BaseChildBo ().setFNumber ( /*saleOrderCodeVo.getSaleOrgCode () */"100" );
        bo.setFSaleOrgId ( FSaleOrgId );
        //销售员
        BaseChildBo FSalerId = new BaseChildBo ().setFNumber ( saleOrderCodeVo.getSaleUserCode () );
        bo.setFSalerId ( FSalerId );
        //日期
        bo.setFDate ( CommonUtil.getDateStrFormat ( saleOrderCodeVo.getSaleDate (), "yyyy-MM-dd" ) );
        //客户
        BaseChildBo FCustId = new BaseChildBo ().setFNumber ( saleOrderCodeVo.getCustomerCode () );
        bo.setFCustId ( FCustId );
        //销售组
        BaseChildBo FSaleGroupId = new BaseChildBo ().setFNumber ( saleOrderCodeVo.getSaleGroupCode () );
        bo.setFSaleGroupId ( FSaleGroupId );
        //销售部门
        BaseChildBo FSaleDeptId = new BaseChildBo ().setFNumber ( saleOrderCodeVo.getSaleDeptCode () );
        bo.setFSaleDeptId ( FSaleDeptId );
        //收货方
        BaseChildBo FReceiveId = new BaseChildBo ().setFNumber ( saleOrderCodeVo.getReceivingPartyCode () );
        bo.setFReceiveId ( FReceiveId );
        //结算方
        BaseChildBo FSettleId = new BaseChildBo ().setFNumber ( saleOrderCodeVo.getSettlementPartyCode () );
        bo.setFSettleId ( FSettleId );
        //付款方
        BaseChildBo FChargeId = new BaseChildBo ().setFNumber ( saleOrderCodeVo.getPayerCode () );
        bo.setFChargeId ( FChargeId );
        //变更原因
        bo.setFChangeReason ( saleOrderCodeVo.getChangeReason () );

        //组装财务信息
        SaleOrderFinanceBo financeBo = new SaleOrderFinanceBo ();
        //结算币别
        financeBo.setFSettleCurrId ( saleOrderCodeVo.getSettleCurrencyCode () );
        //是否含税
        financeBo.setFIsIncludedTax ( "1".equals ( saleOrderCodeVo.getIsTax () ) ? true : false );
        //结算方式
        BaseChildBo FSettleModeId = new BaseChildBo ().setFNumber ( saleOrderCodeVo.getSettlementTypeCode () );
        financeBo.setFSettleModeId ( FSettleModeId );
        //收款条件
        BaseChildBo FRecConditionId = new BaseChildBo ().setFNumber ( saleOrderCodeVo.getPaymentTermsCode () );
        financeBo.setFRecConditionId ( FRecConditionId );
        bo.setFSaleOrderFinance ( financeBo );

        //组装物料明细
        List<SaleOrderDetailBo> saleOrderDetailBos = assembleSaleOrderDetailBo ( saleOrderCodeVo.getId () );
        bo.setFSaleOrderEntry ( saleOrderDetailBos );
        //2.明细列表
        return bo;
    }


    /**
     * 组装付款明细
     * @param saleOrderId
     * @return
     */
    private List<SaleOrderDetailBo> assembleSaleOrderDetailBo (String saleOrderId) {
        List<SaleOrderDetailBo> saleOrderDetailBos = new ArrayList<> ();
        List<MaterialDetailEntity> list = iMaterialDetailService.list ( new LambdaQueryWrapper<MaterialDetailEntity> ().
                eq ( MaterialDetailEntity :: getRelationId, saleOrderId ) );
        list.forEach ( detail -> {
            SaleOrderDetailBo sale = new SaleOrderDetailBo ();
            //物料编码必填
            BaseChildBo FMaterialId = new BaseChildBo ().setFNumber ( detail.getMaterialCode () );
            sale.setFMaterialId ( FMaterialId );
            //销售单位必填
            BaseChildBo FUnitID = new BaseChildBo ().setFNumber ( detail.getPurchaseUnit () );
            sale.setFUnitID ( FUnitID );
            //单价
            sale.setFPrice ( detail.getPrice () );
            //计价单位必填
            BaseChildBo FPriceUnitId = new BaseChildBo ().setFNumber ( detail.getPricingUnit () );
            sale.setFPriceUnitId ( FPriceUnitId );
            //结算组织必填
            SysDept one = iSysDeptService.getOne ( new LambdaQueryWrapper<SysDept> ().eq ( SysDept :: getDeptId, detail.getSettlementDept () ) );
            BaseChildBo FSettleOrgIds = new BaseChildBo ().setFNumber ( /*one.getDeptCode ()*/ "100" );
            sale.setFSettleOrgIds ( FSettleOrgIds );
            //要货日期必填
            sale.setFDeliveryDate ( CommonUtil.getDateStrFormat ( detail.getDeliveryDate (), "yyyy-MM-dd" ) );
            //库存单位必填
            BaseChildBo FStockUnitID = new BaseChildBo ().setFNumber ( detail.getInventoryUnit () );
            sale.setFStockUnitID ( FStockUnitID );
            //销售数量
            sale.setFQty ( detail.getNumber () );
            //计价数量
            sale.setFPriceUnitQty ( detail.getPricingNum () );
            //含税单价
            sale.setFTaxPrice ( detail.getTaxPrice () );
            //是否赠品
            sale.setFIsFree ( detail.getIsGiveaway () );
            //税率
            sale.setFEntryTaxRate ( detail.getTaxRate () );
            //货主类型
            sale.setFOwnerTypeId ( detail.getCargoOwnerType () );
            //货主
            BaseChildBo FOwnerId = new BaseChildBo ().setFNumber ( detail.getCargoOwner () );
            //sale.setFOwnerId ( FOwnerId );
            saleOrderDetailBos.add ( sale );
        } );
        return saleOrderDetailBos;
    }

}
